package core.proto;

import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import javax.swing.JComponent;
import javax.swing.JToolTip;
import javax.swing.Popup;
import javax.swing.PopupFactory;
import javax.swing.ToolTipManager;

import net.htmlparser.jericho.Source;
import net.htmlparser.jericho.TextExtractor;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;

import core.util.logging.UserLogWriter;
import core.util.logging.constants.Action;
import core.util.logging.constants.Location;

import app.constants.CollabVizConstants;
import app.exceptions.CollabVizException;
import app.util.PropertyLoaderUtil;
import static app.constants.CollabVizConstants.*;

public final class Util {

	static final DateFormat dateFormat = new SimpleDateFormat( DATE_FORMAT_NOW );
	protected static final DateFormat logDateFormat = new SimpleDateFormat( "yyyy-MM-dd HH-mm" );
	protected static Date logFileCreationTime; // Time used to create log files.   
	
	private static int ADJUSTED_WIDTH = WINDOW_WIDTH;
	private static int ADJUSTED_HEIGHT = WINDOW_HEIGHT;
	
	public static void setAdjustedHeight(int height){
		ADJUSTED_HEIGHT = height;
	}
	
	static {
		logFileCreationTime = new Date(System.currentTimeMillis());
	}
	
	static TextExtractor createHtmlTextExtractor(File htmlFile) throws MalformedURLException, IOException{
		TextExtractor extractor = new TextExtractor(new Source(htmlFile.toURI().toURL()));
		extractor.setIncludeAttributes(false);
		extractor.setExcludeNonHTMLElements(true);
		return extractor;
	}
	
	static URL getResourceUrl(String resource)  {
		try {
			if (resource.startsWith("/")){
				resource = resource.substring(1);
			}
			return new URL(InfoViz.codebase().toString() + resource);
		} catch (MalformedURLException e) {
			throw new Error("Bad url");
		}
	}
	
	static Object readObject(String filePath) {
		ObjectInputStream in;
		FileInputStream fin = null;
		try{
			fin = new FileInputStream(filePath);
			in = new ObjectInputStream(fin);
			return in.readObject();
		} catch (IOException ioe){
			throw new Error(ioe);
		} catch (ClassNotFoundException e) {
			throw new Error(e);
		} finally {
			if (fin != null){
				try {
					fin.close();
				} catch (IOException e) {
				}
			}
		}
	}

	static void writeObject (Object obj, String filePath){
		ObjectOutputStream out;
		FileOutputStream fout = null;
		try{
			fout = new FileOutputStream(filePath);
			out = new ObjectOutputStream(fout);
			out.writeObject(obj);
		} catch(IOException ioe){
			throw new Error(ioe);
		} finally {
			if (fout != null){
				try {
					fout.close();
				} catch (IOException e) {
				}
			}
		}
	}

	public static String removeDoubleSlash(String path){
		return path.replace("\\\\", "\\");
	}

	public static File getFile (String folder, String filename) {
		return new File(new File(folder), filename);
	}

	public static String getProperty(String propertyName) {
		try {
			return PropertyLoaderUtil.getProp(propertyName);
		} catch (CollabVizException e) {
			throw new Error(e);
		}
	}

	public static String getXmlOutputFilePath () {
		File folder;
		folder = new File(NOTEPAD_HIGHLIGHT_FOLDER);
		return new File(folder, HISTORY_FILE_NAME).getAbsolutePath();
	}

	public static String formatDate(Date date) {
		return dateFormat.format(date);
	}
	
	public static String generateLogFilePath(String logFileName) {
			String date = logDateFormat.format(logFileCreationTime);
			System.out.println(date);
			return String.format("%s-%s-%s.txt", FilenameUtils.concat(LOG_FOLDER, logFileName), InfoViz.UserID, date);
	}

	/**
	 * Shortcut to print to screen. 
	 * @param obj
	 */
	public static void p(Object obj){
		System.out.println(obj);
	}

	/**
	 * Shortcut to print an error message. 
	 * @param obj
	 */
	public static void perr(Object obj){
		System.err.println(obj);
	}

	public static int getVizWidth(){
		return ADJUSTED_WIDTH - getFavoritesWidth();
	}

	public static int getVizHeight(){
		return (int) (ADJUSTED_HEIGHT * VIZ_NOTES_SPLIT_RATIO);
	}

	public static int getDocWidth() {
		return (int) (ADJUSTED_WIDTH * LEFT_RIGHT_SPLIT_RATIO * (1 - FILE_TREE_SPLIT_RATIO));
	}

	public static int getDocHeight(){
		return (int) (ADJUSTED_HEIGHT * TOP_BOTTOM_SPLIT_RATIO);
	}

	public static int getFileTreeHeight(){
		return (int) (ADJUSTED_HEIGHT * TOP_BOTTOM_SPLIT_RATIO);
	}

	public static int getFileTreeWidth(){
		return (int) (ADJUSTED_WIDTH * LEFT_RIGHT_SPLIT_RATIO * FILE_TREE_SPLIT_RATIO);
	}

	public static int getFavoritesHeight(){
		return ADJUSTED_HEIGHT - getDocHeight();
	}

	public static int getFavoritesWidth() {
		return getDocWidth() + getFileTreeWidth();
	}

	public static int getNoteAreaHeight (){
		return ADJUSTED_HEIGHT - getVizHeight();
	}

	public static int getNoteAreaWidth(){
		return getVizWidth();
	}
}